struct Date {
    year: i32,
    month: i32,
}

enum PersonType {
    Male,     // 男职工
    Female55, // 原法定退休年龄 55 周岁女职工
    Female50, // 原法定退休年龄 50 周岁女职工
}

struct RetirementPolicy {
    base_age: i32,         // 基准退休年龄
    delay_start_year: i32, // 延迟退休开始年份
    max_delay_months: i32, // 最大延迟月数
    monthly_step: i32,     // 每年延迟步长(月)
}

pub fn retire_time(time: &str, tp: &str) -> String {
    let birth_date = parse_date(time);

    let person_type = parse_person_type(tp);

    let policy = get_policy(&person_type);

    let (retire_date, delay_months) = calculate_retirement_date(&birth_date, &policy);

    let retire_age = calculate_retirement_age(&birth_date, &retire_date);

    let age_str = if retire_age.fract() == 0.0 {
        format!("{}", retire_age as i32)
    } else {
        format!("{:.2}", retire_age)
    };

    format!("{},{},{}", format_date(&retire_date), age_str, delay_months)
}

fn parse_date(date_str: &str) -> Date {
    let parts: Vec<&str> = date_str.split('-').collect();
    Date {
        year: parts[0].parse().unwrap(),
        month: parts[1].parse().unwrap(),
    }
}

fn parse_person_type(tp: &str) -> PersonType {
    match tp {
        "男职工" => PersonType::Male,
        "原法定退休年龄55周岁女职工" => PersonType::Female55,
        "原法定退休年龄50周岁女职工" => PersonType::Female50,
        _ => panic!("Unknown person type: {}", tp),
    }
}

fn get_policy(person_type: &PersonType) -> RetirementPolicy {
    match person_type {
        PersonType::Male => RetirementPolicy {
            base_age: 60,
            delay_start_year: 2025,
            max_delay_months: 36,
            monthly_step: 3,
        },
        PersonType::Female55 => RetirementPolicy {
            base_age: 55,
            delay_start_year: 2025,
            max_delay_months: 36,
            monthly_step: 4,
        },
        PersonType::Female50 => RetirementPolicy {
            base_age: 50,
            delay_start_year: 2025,
            max_delay_months: 60,
            monthly_step: 4,
        },
    }
}

fn add_months(date: &Date, months: i32) -> Date {
    let total_months = date.month + months;
    let year_diff = (total_months - 1) / 12;
    let new_month = ((total_months - 1) % 12) + 1;

    Date {
        year: date.year + year_diff,
        month: new_month,
    }
}

fn add_years(date: &Date, years: i32) -> Date {
    Date {
        year: date.year + years,
        month: date.month,
    }
}

fn calculate_retirement_date(birth_date: &Date, policy: &RetirementPolicy) -> (Date, i32) {
    let base_retire_date = add_years(birth_date, policy.base_age);

    if base_retire_date.year < policy.delay_start_year {
        return (base_retire_date, 0);
    }

    let mut delay_months;

    if base_retire_date.year == policy.delay_start_year {
        delay_months = base_retire_date.month * policy.monthly_step / 12;
        if base_retire_date.month > 0 {
            delay_months = delay_months.max(1);
        }
    } else {
        let years_after_policy = base_retire_date.year - policy.delay_start_year;
        delay_months = (years_after_policy * policy.monthly_step).min(policy.max_delay_months);
    }

    let final_retire_date = add_months(&base_retire_date, delay_months);

    (final_retire_date, delay_months)
}

fn calculate_retirement_age(birth_date: &Date, retire_date: &Date) -> f64 {
    let months_diff =
        (retire_date.year - birth_date.year) * 12 + (retire_date.month - birth_date.month);
    months_diff as f64 / 12.0
}

fn format_date(date: &Date) -> String {
    format!("{}-{:02}", date.year, date.month)
}
